package com.ecoolex.chinadutyfree.retailer.core.manager;

import java.sql.Date;
import java.time.Instant;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ecoolex.chinadutyfree.retailer.core.dao.GoodsDAO;
import com.ecoolex.chinadutyfree.retailer.entity.Goods;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsExample;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsWithBLOBs;
import com.ecoolex.chinadutyfree.retailer.entity.GoodsWithBLOBs.Column;
import com.ecoolex.chinadutyfree.retailer.enums.GoodsStatus;
import com.ecoolex.chinadutyfree.retailer.pojo.EditSpecGroupDTO;
import com.ecoolex.chinadutyfree.retailer.pojo.QueryGoodsDTO;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;


@Service
public class GoodsManager {

	@Autowired
	private GoodsDAO dao;

	@Autowired
	private GoodsShopwindowManager goodsShopwindowManager;

	@Autowired
	private GoodsSpecGroupManager goodsSpecGroupManager;

	@Autowired
	private GoodsProductManager goodsProductManager;

	@Autowired
	private DirectMailGoodsManager directMailGoodsManager;

	private void verify(Goods record, List<String> shopwindowList, List<EditSpecGroupDTO> specGroup) {
		BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getName()), ResultCode.VERIFY.build(10), "商品名称为空");

		BizAssert.isTrue(Check.notNullOrEmpty(shopwindowList), ResultCode.VERIFY.build(11), "商品至少需要一张橱窗图");
		BizAssert.isTrue(Check.notNullOrEmpty(specGroup), ResultCode.VERIFY.build(12), "商品至少需要一个规格");
	}

	@Transactional
	public GoodsWithBLOBs add(GoodsWithBLOBs record, List<String> shopwindowList, List<EditSpecGroupDTO> specGroup, String createUser) {
		verify(record, shopwindowList, specGroup);

		record.setStatus(GoodsStatus.ENABLE.real());
		record.setDeleted(Goods.NOT_DELETED);
		record.setCreateUser(createUser);
		record.setCreateTime(Date.from(Instant.now()));
		record.setUpdateUser(createUser);
		record.setUpdateTime(Date.from(Instant.now()));

		dao.insert(record);

		updateGoods(record, shopwindowList, specGroup, createUser);
		return record;
	}

	@Transactional
	public GoodsWithBLOBs update(GoodsWithBLOBs record, List<String> shopwindowList, List<EditSpecGroupDTO> specGroup, String updateUser) {
		verify(record, shopwindowList, specGroup);

		record.setUpdateUser(updateUser);
		record.setUpdateTime(Date.from(Instant.now()));

		dao.updateByPrimaryKeySelective(record,
			Column.excludes(Column.status, Column.deleted, Column.createUser, Column.createTime));

		updateGoods(record, shopwindowList, specGroup, updateUser);
		return record;
	}

	private void updateGoods(GoodsWithBLOBs record, List<String> shopwindowList, List<EditSpecGroupDTO> specGroup, String updateUser) {
		// 橱窗
		goodsShopwindowManager.update(record, shopwindowList, updateUser);
		// 规格
		goodsSpecGroupManager.update(record, specGroup, updateUser);
		// 产品
		goodsProductManager.update(record, specGroup, updateUser);
	}

	@Transactional
	public void delete(GoodsWithBLOBs record, String updateUser) {
		long directMailGoods = directMailGoodsManager.countByGoodsId(record.getGoodsId());
		BizAssert.isTrue(Check.isLessThan(directMailGoods, 1L),
			ResultCode.BIZ.build(10),
			"有{}个直邮商品使用了该商品,无法删除",
			directMailGoods);

		record.setDeleted(Goods.IS_DELETED);
		record.setUpdateUser(updateUser);
		record.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(record, Column.deleted,Column.updateUser,Column.updateTime);

		// TODO 删除关联的商品
		// 删除橱窗
		goodsShopwindowManager.deleteByGoodsId(record.getGoodsId(), updateUser);
		// 删除规格
		goodsSpecGroupManager.deleteByGoodsId(record.getGoodsId(), updateUser);
		// 删除产品
		goodsProductManager.deleteByGoodsId(record.getGoodsId(), updateUser);
	}

	public GoodsWithBLOBs getById(Integer goodsId) {
		return dao.selectByPrimaryKeyWithLogicalDelete(goodsId, GoodsWithBLOBs.NOT_DELETED);
	}

	public Pagination<GoodsWithBLOBs> query(QueryGoodsDTO query, Sorting[] sorts, Page page) {
		GoodsExample example = new GoodsExample();
		GoodsExample.Criteria criteria = example.createCriteria();

		if (Check.notNullOrTrimEmpty(query.getName())) {
			criteria.andNameLike('%' + query.getName()
				+ '%');
		}
		if (Check.notNull(query.getBrandId())) {
			criteria.andBrandIdEqualTo(query.getBrandId());
		}
		if (Check.notNull(query.getCategoryId())) {
			criteria.andCategoryIdEqualTo(query.getCategoryId());
		}
		if (Check.notNullOrTrimEmpty(query.getCoded())) {
			criteria.andCodedEqualTo(query.getCoded());
		}
		if (Check.notNullOrTrimEmpty(query.getBarCoded())) {
			criteria.andCodedEqualTo(query.getBarCoded());
		}
		if (Check.notNullOrTrimEmpty(query.getUnit())) {
			criteria.andUnitEqualTo(query.getUnit());
		}
		if (Check.notNullOrTrimEmpty(query.getCurrencyType())) {
			criteria.andCurrencyTypeEqualTo(query.getCurrencyType());
		}
		if (Check.notNull(query.getAfterServiceId())) {
			criteria.andAfterServiceIdEqualTo(query.getAfterServiceId());
		}
		if (Check.notNull(query.getStatus())) {
			criteria.andStatusEqualTo(query.getStatus());
		}

		criteria.andDeletedEqualTo(Goods.NOT_DELETED);
		example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());

		return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExampleWithBLOBs(example));
	}

}